#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<assert.h>
#include<stdlib.h>
#include<unistd.h>

#define NUM 10

typedef void (*func_t)(); //函数指针

func_t handlerTask[NUM];

//样例任务
void task1()
{
    printf("handler task1\n");
}
void task2()
{
    printf("handler task1\n");
}
void task3()
{
    printf("handler task1\n");
}

void loadTask()
{
    memset(handlerTask, 0, sizeof(handlerTask));
    handlerTask[0] = task1;
    handlerTask[1] = task1;
    handlerTask[2] = task1;
}

int main()
{
    pid_t id = fork();
    assert(id != -1);
    
    if(id == 0)
    {
        //child
        int cnt = 10;
        while(cnt)
        {
            printf("child running, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt--);
            sleep(3);
            // int* p = NULL;
            // *p =100;
        }
        exit(11);
    }
   loadTask();
   //parent
   int status = 0;
   while(1)  
   {    
       pid_t ret = waitpid(id, &status, WNOHANG); //WHONANG: 非阻塞->子进程没有退出，父进程检测的时候，立即返回
       if(ret == 0)
       {
           //waitpid调用成功 && 子进程没退出
           //子进程没有退出，我的waitpid没有等待失败，仅仅是检测到了子进程没退出
           printf("wait done, but child is running...., parent running other things\n");
           for(int i=0; handlerTask[i] != 0; i++)
           {
               handlerTask[i](); // 采用回调的方式，执行我们想让父进程在空闲的时候做的事情
           }
       }
       else if(ret > 0) // 也可以直接写成ret == pid 
       {
           // 1. waitpid调用成功 && 子进程退出了
           
           printf("wait success, exit code: %d, sign: %d\n", (status>>8)&0xFF, status & 0x7F);
           break;  
       }
       else
       {
           // waitpis调用失败
           printf("waitpid call failed\n");
           break;
       }
       sleep(1);
   }












    //parent
   // int status = 0;
   // // 1. 让OS释放子进程的僵尸状态
   // // 2. 获取子进程的退出结果
   // // 在等待期间，子进程没有退出的时候，父进程只能阻塞等待
   // int ret = waitpid(id, &status, 0);
   // if(ret > 0)
   // {
   //     //是否正常退出
   //     if(WIFEXITED(status))
   //     {
   //         //判断子进程运行结果是否OK
   //         printf("exit code: %d\n", WEXITSTATUS(status));
   //         
   //     }
   //     else 
   //     {
   //         // 
   //         printf("wait failed\n");
   //     }
   //     //  printf("wait success, exit code: %d, sign: %d\n", (status>>8)&0xFF, status & 0x7F);
   // }
   // return 0;

}
